/* File: ast_type.cc
 * -----------------
 * Implementation of type node classes.
 */
#include <string.h>
#include "ast_type.h"
#include "ast_decl.h" 
/* Class constants
 * ---------------
 * These are public constants for the built-in base types (int, double, etc.)
 * They can be accessed with the syntax Type::intType. This allows you to
 * directly access them and share the built-in types where needed rather that
 * creates lots of copies.
 */

Type *Type::intType    = new Type("int");
Type *Type::doubleType = new Type("double");
Type *Type::voidType   = new Type("void");
Type *Type::boolType   = new Type("bool");
Type *Type::nullType   = new Type("null");
Type *Type::stringType = new Type("string");
Type *Type::errorType  = new Type("error"); 

Type::Type(const char *n) {
    Assert(n != NULL);
    	typeName = strdup(n);
}

bool Type::equals(Type *t) {
        if (this == Type::errorType) {
                return true;
        }
        if (this == Type::nullType && dynamic_cast<NamedType*>(t)) {
                return true;
        }
        return this == t;
}
	
NamedType::NamedType(Identifier *i) : Type(*i->GetLocation()) {
    Assert(i != NULL);
    (id=i)->SetParent(this);
} 

bool NamedType::equals(Type *t) {
        NamedType *n = dynamic_cast<NamedType*>(t);
        if ( n == NULL ) {
                return false;
        }

        return (strcmp((t->getId()->getName()), (id->getName())) == 0);
}


ArrayType::ArrayType(yyltype loc, Type *et) : Type(loc) {
    Assert(et != NULL);
    (elemType=et)->SetParent(this);
}

ArrayType::ArrayType(Type *et) : Type() {
    Assert(et != NULL);
    (elemType=et)->SetParent(this);
}

bool ArrayType::equals(Type *t) {
        ArrayType *o = dynamic_cast<ArrayType*>(t);
        if (o == NULL) {
                return false;
        }
        return elemType->equals(o->elemType);
}
